/**
 * Copyright 2014 opencxa.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.cxa.rpc.cloud.device.tests;

import static org.junit.Assert.*;

import java.util.concurrent.TimeUnit;

import org.cxa.rpc.cloud.device.CloudDevice;
import org.cxa.rpc.cloud.server.CloudServer;
import org.cxa.rpc.cloud.server.IoBroker;
import org.cxa.rpc.session.SessionManager;
import org.junit.BeforeClass;
import org.junit.Test;

/**
 * @author Christopher Armenio
 */
public class CloudDeviceTests
{
	private static final String CLIENT_SERIAL_NUM = "9979f48c-e9e3-4040-aecd-0a0784f66c47";
	private static final String CLIENT_PASSCODE = "5221d373-3df6-4d92-a2a2-af0c18d3811b";
	private static CloudServer server = null;
	
	
	@BeforeClass
	public static void first() throws Exception
	{
		// start our cloud server and wait for it to start
		server = new CloudServer();
		assertTrue(server.waitForStart(10, TimeUnit.SECONDS));
	}
	
	
	@Test
	public void test_connectDisconnect()
	{
		CloudDevice client = new CloudDevice(CLIENT_SERIAL_NUM, CLIENT_PASSCODE, false);
		client.debug_skipAuthentication();
		
		// instruct the client to connect
		client.connect();
		assertTrue("client did not connect quickly", client.waitForConnect(10, TimeUnit.SECONDS));
		try{ Thread.sleep(5000); } catch(InterruptedException e) { }
		
		// client reports connected...now make sure the IOBroker concurs
		assertTrue("ioBroker reports no client", IoBroker.getSingleton().debug_getConnectedClients().size() == 1);
		// and make sure Jetty concurs
		assertTrue("jetty reports no client", server.getNumOpenConnections_jetty() == 1);
		
		// now, instruct the client to disconnect
		client.disconnect();
		assertTrue("client did not disconnect quickly", client.waitForDisconnect(10, TimeUnit.SECONDS));
		try{ Thread.sleep(5000); } catch(InterruptedException e) { }
		
		// client reports disconnected...now make sure the IOBroker concurs
		assertTrue("ioBroker reports client still connected", IoBroker.getSingleton().debug_getConnectedClients().size() == 0);
		// and make sure jetty concurs
		assertTrue("jetty reports client still connected", server.getNumOpenConnections_jetty() == 0);
	}
	
	
	@Test
	public void test_keepAliveFailure()
	{
		CloudDevice client = new CloudDevice(CLIENT_SERIAL_NUM, CLIENT_PASSCODE, false);
		client.debug_skipAuthentication();
		
		// instruct the client to connect
		client.connect();
		assertTrue("client did not connect quickly", client.waitForConnect(10, TimeUnit.SECONDS));
		try{ Thread.sleep(5000); } catch(InterruptedException e) { }
		
		// client reports connected...now make sure the IOBroker concurs
		assertTrue("ioBroker reports no client", IoBroker.getSingleton().debug_getConnectedClients().size() == 1);
		// and make sure Jetty concurs
		assertTrue("jetty reports no client", server.getNumOpenConnections_jetty() == 1);
		
		// now instruct the client to stop responding to keepalives
		client.debug_stopRespondingToKeepAlives();
		
		// now wait for longer than the keepalive timeout time
		try{ Thread.sleep((long)(1.5 * SessionManager.SESSION_TIMEOUT_PERIOD_MS)); } catch(Exception e) { }
		
		// make sure ioBroker and jetty both think they are disconnected
		assertTrue("ioBroker reports client still connected", IoBroker.getSingleton().debug_getConnectedClients().size() == 0);
		assertTrue("jetty reports client still connected", server.getNumOpenConnections_jetty() == 0);
	}
	
	
	@Test
	public void test_authentication()
	{
		while(true){ Thread.yield(); }
		
		/*
		CloudDevice client = new CloudDevice(CLIENT_SERIAL_NUM, CLIENT_PASSCODE, false);
		
		// instruct the client to connect
		client.connect();
		
		assertTrue("client did not connect quickly", client.waitForConnect(10, TimeUnit.SECONDS));
		try{ Thread.sleep(5000); } catch(InterruptedException e) { }
		
		// client reports connected...now make sure the IOBroker concurs
		assertTrue("ioBroker reports no client", IoBroker.getSingleton().debug_getConnectedClients().size() == 1);
		// and make sure Jetty concurs
		assertTrue("jetty reports no client", server.getNumOpenConnections_jetty() == 1);
		
		
		try{ Thread.sleep(30000); } catch(InterruptedException e) { }
		
		
		// now, instruct the client to disconnect
		client.disconnect();
		assertTrue("client did not disconnect quickly", client.waitForDisconnect(10, TimeUnit.SECONDS));
		try{ Thread.sleep(5000); } catch(InterruptedException e) { }
		
		// client reports disconnected...now make sure the IOBroker concurs
		assertTrue("ioBroker reports client still connected", IoBroker.getSingleton().debug_getConnectedClients().size() == 0);
		// and make sure jetty concurs
		assertTrue("jetty reports client still connected", server.getNumOpenConnections_jetty() == 0);
		*/
	}
}
